// index.js
// scale-page/index.js
const CryptoJS = require('crypto-js')
const request = require('../../utils/request')
import {
  CustomRouteType
} from '../../utils/custom-route/index'
// 获取应用实例
import devNameFilter from './module/devNameFilter';
import devMacFilter from './module/devMacFilter';

function inArray(arr, key, val) {
  for (let i = 0; i < arr.length; i++) {
    if (arr[i][key] === val) {
      return i;
    }
  }
  return -1;
}

// ArrayBuffer转16进度字符串示例
function ab2hex(buffer) {
  var hexArr = Array.prototype.map.call(
    new Uint8Array(buffer),
    function (bit) {
      return ('00' + bit.toString(16)).slice(-2)
    }
  )
  return hexArr.join('');
}

Page({
  data: {
    isScan: true,
    username: '',
    passworld: '',
    devices: [],
    connected: false,
    chs: [],
    filterLoop: false,
    menuListLoop: false,
    theDbm: false,
    theNewDbm: false,
    filterDevValue: '',
    secretKey: 'a90e7d2eb24c4b8b88994ab065e377d3', // 加解密用的key
    myOpenId: '',
    myUserId: '',
    myIsAdmin: false,
    myCreateTime: '',
    userByDevList: [],
    clickIsTrue: false,
    allAuth: '',
    devAuthChecking: '',
    userIsExpire: '',
    stopOptTimeOut: '',
    onRefreshTimeOut: '',
    pauseDownRefresh: true
  },

  onShareAppMessage() {
    return {
      title: '蓝牙配网工具ALM',
      path: '/pages/index/index',
      imageUrl: '../../res/img/common/ALM-IoT2.png'
    }
  },

  onLoad(options) {
    // 开始获取用户信息以及查询用户权限。
    this.getSystemInfo()
    this.getSecretId()
    this.getAppletAuthInfo()
  },
  getAppletAuthInfo() {
    request.post('/getAppletAuthInfo', {}).then(res => {
      if (Number(res.code) === 0) {
        this.data.allAuth = res.data.wxAllAuth
        this.data.devAuthChecking = res.data.wxDevAuthChecking
      }

    })
  },
  panel(e) {
    console.log(this.data.devices);
    this.filterLoop = !e.currentTarget.dataset.loop
    this.setData({
      filterLoop: this.filterLoop
    })
  },

  menuListPanel(e) {
    this.menuListLoop = !e.currentTarget.dataset.loop
    this.setData({
      menuListLoop: this.menuListLoop
    })
  },

  cancelEventBubbling(e) {
    if (e.currentTarget.dataset['openbluetoothadapter']) {
      this.openBluetoothAdapter()
    }
    // if (e.currentTarget.dataset['stopbluetoothadapter']) {
    //   this.stopOpt()
    //   // 使按钮变灰不可点击
    //   this.disableScanClick()
    // }
  },

  disableScanClick(time) {
    let _this = this
    // 关闭定时器
    clearTimeout(_this.data.stopOptTimeOut);

    _this.data.pauseDownRefresh = false
    this.setData({
      isClick: true
    })
    this.data.stopOptTimeOut = setTimeout(function () {
      // 在这里编写需要定时执行的代码
      _this.stopOpt()
    }, time);
  },

  sliderChangeVlue(event) {
    this.theDbm = event.detail.value;
    this.setData({
      theDbm: this.theDbm
    })
    // 根据滑动的位置占比，设置具体的值
    // const adjustedValue = min + percent * (max - min);
  },
  resetTheDbm() {
    this.filterDevValue = ''
    this.theDbm = false;
    this.setData({
      theDbm: this.theDbm,
      filterDevValue: this.filterDevValue
    })
  },
  openBluetoothAdapter() {
    wx.openBluetoothAdapter({
      success: (res) => {
        this.stopOpt()
        this.startBluetoothDevicesDiscovery()
      },
      fail: (res) => {
        if (res.errno === 1500102) {
          this.errorResult('蓝牙未开启')
        }
        if (res.errno === 103) {
          this.errorResult('蓝牙未授权')
        }
      }
    })
  },
  startBluetoothDevicesDiscovery() {
    if (this._discoveryStarted) {
      return
    }
    let _this = this
    this._discoveryStarted = true
    wx.startBluetoothDevicesDiscovery({
      allowDuplicatesKey: true,
      success: (res) => {
        // 使按钮变灰不可点击
        this.disableScanClick(10000)
        this.onBluetoothDeviceFound()
      },
      fail(e) {
        _this.errorResult('蓝牙启动失败')
        _this.stopOpt()
        console.log(e);
      }
    })
  },
  createBLEConnection(e) {
    const ds = e.currentTarget.dataset
    const deviceId = ds.deviceId
    const name = ds.name
    wx.createBLEConnection({
      deviceId,
      success: (res) => {
        this.setData({
          connected: true,
          name,
          deviceId,
        })
        this.getBLEDeviceServices(deviceId)
      }
    })
  },
  getBLEDeviceServices(deviceId) {
    wx.getBLEDeviceServices({
      deviceId,
      success: (res) => {
        for (let i = 0; i < res.services.length; i++) {
          if (res.services[i].isPrimary) {
            this.getBLEDeviceCharacteristics(deviceId, res.services[i].uuid)
            return
          }
        }
      }
    })
  },
  onBluetoothDeviceFound() {
    wx.onBluetoothDeviceFound((res) => {
      res.devices.forEach(device => {
        if (!device.name && !device.localName) {
          return
        }

        // 过滤展示的设备
        this.filterDevDBm(device)
      })
    })
  },
  filterDevDBm(device) {
    const idx = inArray(this.data.devices, 'deviceId', device.deviceId)
    let arr = []
    if (idx === -1) {
      this.data.devices[this.data.devices.length] = device
    } else {
      this.data.devices[idx] = device
    }

    // 判断是否点击了“显示我绑定的设备”单选框
    if (this.clickIsTrue) {
      if (this.data.userByDevList.length > 0) {
        this.data.userByDevList.forEach(item => {
          this.data.devices = devMacFilter(this.data.devices, item.devMac)
        })
      }
    }

    // 判断是否用了信号值来进行过滤
    if (this.theDbm && device.RSSI < this.theDbm) {
      for (let index = this.data.devices.length - 1; index > 0; index--) {
        const item = this.data.devices[index];
        if (item.RSSI < this.theDbm) {
          this.data.devices.splice(index, 1);
        }
      }
    }

    // 判断是否输入了设备名称来过滤
    if (this.filterDevValue) {
      this.data.devices.forEach(item => {
        let devName = item.localName ? item.localName : item.name
        let opt = devNameFilter(devName, this.filterDevValue)
        if (opt) {
          arr.push(item)
        }
      })
    }

    this.isScan = false
    this.setData({
      isScan: this.isScan,
      devices: this.filterDevValue ? arr : this.data.devices
    })
  },

  closeBLEConnection() {
    wx.closeBLEConnection({
      deviceId: this.data.deviceId
    })
    this.setData({
      connected: false,
      chs: [],
      canWrite: false,
    })
  },
  getBLEDeviceCharacteristics(deviceId, serviceId) {
    wx.getBLEDeviceCharacteristics({
      deviceId,
      serviceId,
      success: (res) => {
        for (let i = 0; i < res.characteristics.length; i++) {
          let item = res.characteristics[i]
          if (item.properties.read) {
            wx.readBLECharacteristicValue({
              deviceId,
              serviceId,
              characteristicId: item.uuid,
            })
          }
          if (item.properties.write) {
            this.setData({
              canWrite: true
            })
            this._deviceId = deviceId
            this._serviceId = serviceId
            this._characteristicId = item.uuid
            this.writeBLECharacteristicValue()
          }
          if (item.properties.notify || item.properties.indicate) {
            wx.notifyBLECharacteristicValueChange({
              deviceId,
              serviceId,
              characteristicId: item.uuid,
              state: true,
            })
          }
        }
      },
      fail(res) {
        console.error('getBLEDeviceCharacteristics', res)
      }
    })
    // 操作之前先监听，保证第一时间获取数据
    wx.onBLECharacteristicValueChange((characteristic) => {
      const idx = inArray(this.data.chs, 'uuid', characteristic.characteristicId)
      const data = {}
      if (idx === -1) {
        data[`chs[${this.data.chs.length}]`] = {
          uuid: characteristic.characteristicId,
          value: ab2hex(characteristic.value)
        }
      } else {
        data[`chs[${idx}]`] = {
          uuid: characteristic.characteristicId,
          value: ab2hex(characteristic.value)
        }
      }
      this.setData(data)
    })
  },
  showHidePopWindow(e) {
    // 获取用户当前绑定的设备
    this.getUserBandDevListByUserId(this.data.myUserId).then(userByDevList => {
      this.data.userByDevList = userByDevList.data
      this.setData({
        userByDevList: this.data.userByDevList
      })
    })
    let name = e.currentTarget.dataset.name
    wx.showActionSheet({
      alertText: '你当前选择的设备是 ' + name,
      itemList: ['配网', '信息录入', '设置设备名称'],
      // itemList: ['配网', '信息录入', 'MQTT配置'],  这个方法是跳转到配置MQTT页面的 this.skipSettingMQTT(e)
      success: (res) => {
        switch (res.tapIndex) {
          case 0:
            this.jump(e)
            break;
          case 1:
            this.getEnterFloorInfo(e)
            break;
          case 2:
            // this.skipSettingMQTT(e)
            this.skipEditDevNickName(e)
            break;
        }
      },
      fail(res) {
        console.log('取消选项')
      }
    })
  },

  devAndUserIsAuth(devMac) {
    if (!devMac || devMac === 'undefined') {
      return this.errorResult('Mac格式错误')
    }
    let _this = this
    // 获取当前用户是不是管理员，管理员不需要获取他的账号时间
    // 当前总权限是否开启, 当权限关闭后才返回true
    if (this.data.myIsAdmin || !this.data.allAuth) {
      return true
    }

    // 检查后台是否开启了设备使用时间验证
    if (this.data.devAuthChecking) {
      // 检查用户是否没有使用时间了，true就是没有时间了
      if (this.data.userIsExpire) {
        // 进入此判断说明设备没有使用时间了，可以给用户续权
        return this.errorResult('用户使用到期')
      }
    }

    for (let i = 0; i < this.data.userByDevList.length; i++) {
      const item = this.data.userByDevList[i];
      // 判断用户选择的设备是否存在自己的绑定
      if (item.devMac === devMac) {
        return true
      }
    }
    wx.showModal({
      title: '提示',
      content: '你还没有设备使用权限\n是否前往授权操作',
      confirmText: '好',
      success(res) {
        if (res.confirm) {
          _this.skipBandDev(devMac)
        } else if (res.cancel) {
          // console.log('用户点击取消')
        }
      }
    })
    return false
  },

  compareTimes() {
    if (this.data.myCreateTime) {
      // 将后端返回的时间字符串转换为日期对象
      var myCreateDate = new Date(this.data.myCreateTime);
      // 将客户端时间字符串转换为日期对象
      var nowDate = new Date();
      // 比较两个日期对象，如果后者的时间距离大于60天，返回false  (60 * 24 * 60 * 60 * 1000)
      return nowDate > myCreateDate && (nowDate - myCreateDate) < 60 * 24 * 60 * 60 * 1000;
    } else {
      return this.errorResult('时间转换失败')
    }
  },

  formatDevMac(devMac) {
    if (!devMac) {
      return ''
    }
    var arr = devMac.split(":");
    let strs = ''
    arr.forEach(str => {
      strs += str
    })
    return strs
  },

  jump(e) {
    // 以下注释掉的代码都是要的
    let _this = this
    let devMac = this.formatDevMac(e.currentTarget.dataset.deviceId)
    if (this.devAndUserIsAuth(devMac)) {
      wx.navigateTo({
        url: '/pages/setting-network/index?deviceId=' + e.currentTarget.dataset.deviceId +
          '&name=' + e.currentTarget.dataset.name,
        routeType: CustomRouteType.HalfScreenDialog
      });
    }
    //  else {
    //   this.errorResult('未授权的设备')
    // }
  },
  stopOpt() {
    let _this = this
    // 跳转页面后停止扫描
    wx.stopBluetoothDevicesDiscovery({
      success(res) {
        _this.isScan = true
        _this._discoveryStarted = false
        _this.data.pauseDownRefresh = true
        _this.setData({
          isScan: _this.isScan,
          isClick: false
        })
      }
    })
  },
  getEnterFloorInfo(e) {
    let _this = this
    wx.navigateTo({
      url: '/pages/floorInfo/index?devMac=' + e.currentTarget.dataset.deviceId +
        '&devName=' + e.currentTarget.dataset.name,
      routeType: CustomRouteType.HalfScreenDialog,
      success: function (res) {
        // _this.stopOpt()
      }
    });
  },
  errorResult(errorInfo) {
    wx.showToast({
      title: errorInfo,
      icon: 'error',
      duration: 2000
    })
  },
  successResult(successInfo) {
    wx.showToast({
      title: successInfo,
      icon: 'success',
      duration: 2000
    })
  },

  // 解密
  decrypt(content) {
    /* content 要解密的内容 */
    let iv = '0000000000000000'
    const secretKey = this.data.secretKey /* 前后端约定好的key */
    const key = CryptoJS.enc.Utf8.parse(secretKey)
    iv = CryptoJS.enc.Utf8.parse(iv)
    const decrypt = CryptoJS.AES.decrypt(content, key, {
      iv: iv,
      mode: CryptoJS.mode.CBC,
      padding: CryptoJS.pad.Pkcs7
    })
    return decrypt.toString(CryptoJS.enc.Utf8)
  },

  encrypt(content) {
    /* content 要加密的内容 */
    let iv = '0000000000000000'
    const secretKey = this.data.secretKey /* 前后端约定好的key */
    // o_nyM63PjAsJ73mdybojD0xo8lyc
    const msg = CryptoJS.enc.Utf8.parse(content)
    const key = CryptoJS.enc.Utf8.parse(secretKey)
    iv = CryptoJS.enc.Utf8.parse(iv)
    const encrypt = CryptoJS.AES.encrypt(msg, key, {
      iv: iv,
      mode: CryptoJS.mode.CBC,
      padding: CryptoJS.pad.Pkcs7
    })
    return encrypt.toString()
  },

  getSecretId() {
    // 首先获取APPID，再利用APPID去查SecretId
    let appId = this.getAppId()
    request.post('/getSecretId', appId).then(res => {
      if (Number(res.code) === 0) {
        // 等于0说明成功且有数据
        let secretIdByAES = res.data.secretIdByAES // 这是从数据库拿出来的加密的secretId
        this.loginGetOpenId(appId, secretIdByAES).then(userInfo => {
          if (!userInfo.openId) {
            return this.errorResult('找不到openID')
          }
          let openId = userInfo.openId;
          // 拿到了用户的openID就行了
          this.data.myOpenId = openId

          // 利用用户的openID获取用户信息
          this.getUserInfo(openId).then(user => {
            console.log(user);
            if (Number(user.code) === 0) {
              // 说明当前用户是存在的
              // 保存用户ID
              this.editUserInfo(user)
            } else {
              // 说明没有找到用户
              // 插入用户的openID
              this.insertUserByOpenId(openId)
            }
          })
        })
      }
    })
  },

  insertUserByOpenId(openId) {
    request.post('/insertUserByOpenId', openId).then(res => {
      if (Number(res.code) === 0) {
        // 保存用户ID
        console.log(res);
        this.editUserInfo(res)
      } else {
        this.errorResult(res.msg)
      }
    })
  },

  editUserInfo(user) {
    this.data.myUserId = user.data.id
    this.data.myIsAdmin = user.data.isAdmin
    this.data.myCreateTime = user.data.createTime
    this.data.userIsExpire = user.data.userIsExpire

    this.setData({
      myUserId: this.data.myUserId,
      myIsAdmin: this.data.myIsAdmin,
      myCreateTime: this.data.myCreateTime,
      userIsExpire: this.data.userIsExpire
    })
  },

  getUserBandDevListByUserId(userId) {
    return new Promise((resolve, reject) => {
      request.post('/getUserBandDevList', userId).then(res => {
        console.log(res);
        resolve(res)
      })
    });
  },

  filterDev(e) {
    this.filterDevValue = e.detail.value
    let arr = []
    this.data.devices.forEach(item => {
      let devName = item.localName ? item.localName : item.name
      let opt = devNameFilter(devName, this.filterDevValue)
      if (opt) {
        arr.push(item)
      }
    })
    console.log('this.data.devices ', this.data.devices);
    this.setData({
      filterDevValue: this.filterDevValue,
      devices: this.filterDevValue ? arr : this.data.devices
    })
  },

  getAppId() {
    return wx.getAccountInfoSync().miniProgram.appId
  },

  loginGetOpenId(appId, secretIdByAES) {
    let secretId = this.decrypt(secretIdByAES) // 将加密的secretId和key传入方法进行解密
    return new Promise((resolve, reject) => {
      wx.login({
        success: res => {
          if (res.code) {
            let info = {
              appId: appId,
              secretId: secretId,
              resCode: res.code
            }
            request.post('/getJsCode2Session', info).then(res => {
              let userInfo = res.data
              resolve(userInfo);
            })
          }
        }
      })
    });
  },

  getUserInfo(openId) {
    return new Promise((resolve, reject) => {
      request.post('/wxGetUserInfo', openId).then(res => {
        resolve(res)
      })
    });
  },

  openCameraBandDev() {
    let _this = this
    wx.scanCode({
      onlyFromCamera: true,
      success(res) {
        let devName = res.result
        if (devName) {
          _this.bandShowActionSheet(devName)
        }
      }
    })
  },

  bandShowActionSheet(devName) {
    let _this = this
    wx.showModal({
      editable: true,
      title: '提示',
      content: '你将会绑定设备：' + devName,
      success(res) {
        if (res.confirm) {
          let user = {
            userId: _this.data.myUserId,
            devName: devName
          }
          _this.bandUserAndDev(user)
        } else if (res.cancel) { }
      }
    })
  },

  bandUserAndDev(user) {
    let _this = this
    request.post('/bandUserAndDev', user).then(res2 => {
      if (Number(res2.code) === 0) {
        // 绑定成功
        _this.successResult('绑定成功')
      } else {
        _this.errorResult(res2.msg)
      }
    })
  },

  showMyDev(e) {
    this.clickIsTrue = e.detail.value.length > 0
  },

  skipBandDev(devMac) {
    wx.navigateTo({
      url: '/pages/band-dev/index?userid=' + this.data.myUserId
        + '&devMac=' + (devMac.length ? devMac : ''),
      routeType: CustomRouteType.HalfScreenDialog
    });
  },

  skipFileUpload() {
    wx.navigateTo({
      url: '/pages/uploader/index'
    });
  },

  saveServiceInfo() {
    wx.navigateTo({
      url: '/pages/save-service-info/index',
      routeType: CustomRouteType.HalfScreenDialog
    });
  },

  getSystemInfo() {
    let _this = this
    wx.getSystemInfo({
      success(res) {
        _this.setData({
          model: res.model,
          pixelRatio: res.pixelRatio,
          windowWidth: res.windowWidth,
          windowHeight: res.windowHeight
        })
      }
    })
  },

  skipSettingMQTT(e) {
    let _this = this
    wx.navigateTo({
      url: '/pages/setting-MQTT/index?devMac=' + e.currentTarget.dataset.deviceId +
        '&devName=' + e.currentTarget.dataset.name,
      routeType: CustomRouteType.HalfScreenDialog,
      success: function (res) {
        // _this.stopOpt()
      }
    });
  },

  skipEditDevNickName(e) {
    wx.navigateTo({
      url: '/pages/edit-dev-nickname/index?devMac=' + e.currentTarget.dataset.deviceId +
        '&devName=' + e.currentTarget.dataset.name,
      routeType: CustomRouteType.HalfScreenDialog,
      success: function (res) {
        // _this.stopOpt()
      }
    });
  },

  skipMyDevs() {
    wx.navigateTo({
      url: '/pages/my-devs/index?userid=',
      routeType: CustomRouteType.HalfScreenDialog,
      success: function (res) {
        // _this.stopOpt()
      }
    });
  },

  skipCheckingAuth() {
    wx.navigateTo({
      url: '/pages/checking-auth/index?myIsAdmin=' + this.data.myIsAdmin +
        '&myUserId=' + this.data.myUserId,
      routeType: CustomRouteType.HalfScreenDialog,
      success: function (res) {
        // _this.stopOpt()
      }
    });
  },

  onRefresh() {
    if (!this.data.pauseDownRefresh) {
      return
    }
    // console.log('我被下拉了');
    // 关闭定时器
    clearTimeout(this.data.onRefreshTimeOut);

    // 开启蓝牙扫描
    this.openBluetoothAdapter()

    // 创建定时器
    this.data.onRefreshTimeOut = setTimeout(() => {
      this.setData({
        triggered: false,
      })
    }, 10000)
  },

  onRestore() {
    // console.log('下拉结束，我回去了');
    // this.stopOpt()
  }
})